package com.acme.chat.ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.border.EmptyBorder;

import com.acme.chat.message.MessageType;
import com.acme.chat.newclient.Client;
import com.acme.chat.newclient.ClientMessage;
import com.acme.chat.newclient.IncommingMessageListener;
import com.acme.chat.newclient.Messages;
import com.acme.chat.newclient.ServerMessage;
import com.acme.chat.newclient.TcpProxyAgent;

public class ChatUi extends JFrame implements ActionListener, IncommingMessageListener {

    private JPanel contentPane;
    private String serverName;
    private int port;

    private Client client;
    private String name;
    private boolean connected;

    private JButton loginButton;
    private JButton settingsButton;
    private JButton exitButton;
    private JButton clearButton;
    private JTextArea logTextArea;
    private JTextArea userTextArea;
    private JList usersList;
    private JTextField nameField;
    private JTextField roomField;
    private JTabbedPane chatTabsPane;

    /**
     * Create the frame.
     */
    public ChatUi() {
        super("Chatik");
        setMinimumSize(new Dimension(320, 240));
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                exit();
            }
        });
        setBounds(100, 100, 555, 545);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        chatTabsPane = new JTabbedPane(JTabbedPane.TOP);
        contentPane.add(chatTabsPane, BorderLayout.CENTER);

                JSplitPane roomSplitPane = new JSplitPane();
                chatTabsPane.addTab("New tab", null, roomSplitPane, null);
                roomSplitPane.setResizeWeight(0.7);
                roomSplitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);

                        userTextArea = new JTextArea();
                        userTextArea.setLineWrap(true);
                        userTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12));
                        userTextArea.addKeyListener(getUserAreaKeyListener());

                                logTextArea = new JTextArea();
                                logTextArea.setEditable(false);
                                logTextArea.setLineWrap(true);

                                        JScrollPane userScrollPane = new JScrollPane(userTextArea);
                                        roomSplitPane.setRightComponent(userScrollPane);

                                                JScrollPane logScrollPane = new JScrollPane(logTextArea);
                                                roomSplitPane.setLeftComponent(logScrollPane);

        JPanel privateMessagePane = new JPanel();
        chatTabsPane.addTab("New tab", null, privateMessagePane, null);
        privateMessagePane.setLayout(new BorderLayout(0, 0));


        JPanel usersListPane = new JPanel();
        contentPane.add(usersListPane, BorderLayout.EAST);
                        usersListPane.setLayout(new BoxLayout(usersListPane, BoxLayout.Y_AXIS));

                        JLabel usersListLabel = new JLabel("Users list");
                        usersListLabel.setToolTipText("Show list of the users in the current room");
                        usersListLabel.setFont(new Font("Tahoma", Font.BOLD, 14));
                        usersListPane.add(usersListLabel);

                                                usersList = new JList(new String[]{"String1", "String2", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"});
                                                usersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
                                                usersList.setVisibleRowCount(10);
                                                JScrollPane usersListScrollPane = new JScrollPane(usersList);
                                                usersListPane.add(usersListScrollPane);

                                                JPanel buttonsPane = new JPanel();
                                                contentPane.add(buttonsPane, BorderLayout.SOUTH);

                                                loginButton = new JButton("Login");
                                                loginButton.setToolTipText("Connect to the server");
                                                loginButton.addActionListener(this);
                                                buttonsPane.add(loginButton);

                                                                                                settingsButton = new JButton("Settings...");
                                                                                                settingsButton.setToolTipText("Here you can change server, port and nick name");
                                                                                                settingsButton.addActionListener(this);
                                                                                                buttonsPane.add(settingsButton);

                                                                                                exitButton = new JButton("Exit");
                                                                                                exitButton.addActionListener(new ActionListener() {
                                                                                                    @Override
                                                                                                    public void actionPerformed(ActionEvent e) {
                                                                                                        exit();
                                                                                                    }
                                                                                                });
                                                                                                buttonsPane.add(exitButton);

                                                                                                JPanel quickSettingsPane = new JPanel();
                                                                                                contentPane.add(quickSettingsPane, BorderLayout.NORTH);

                                                                                                JLabel nameLabel = new JLabel("Nick name:");
                                                                                                quickSettingsPane.add(nameLabel);

                                                                                                nameField = new JTextField();
                                                                                                quickSettingsPane.add(nameField);
                                                                                                nameField.setColumns(10);

                                                                                                JLabel roomLabel = new JLabel("Room:");
                                                                                                quickSettingsPane.add(roomLabel);

                                                                                                roomField = new JTextField();
                                                                                                roomField.setText("Main");
                                                                                                quickSettingsPane.add(roomField);
                                                                                                roomField.setColumns(10);

                                                                                                clearButton = new JButton("Clear log");
                                                                                                clearButton.addActionListener(new ActionListener() {
                                                                                                    @Override
                                                                                                    public void actionPerformed(ActionEvent e) {
                                                                                                        logTextArea.setText("");
                                                                                                        logTextArea.setCaretPosition(0);
                                                                                                    }
                                                                                                });
                                                                                                quickSettingsPane.add(clearButton);

                                                                                                initUi();
    }

    private KeyListener getUserAreaKeyListener() {
        KeyListener kl = new KeyListener() {

            @Override
            public void keyPressed(KeyEvent e) {
                if (!connected) {
                    return;
                }
                if ((e.getKeyCode() == KeyEvent.VK_ENTER) && (e.getModifiers() == 2) ) {
                    String userText = userTextArea.getText();
                    client.sendMessage(new ClientMessage(MessageType.MESSAGE, userText));
                    userTextArea.setText("");
                    userTextArea.setCaretPosition(0);
                }
            }

            @Override
            public void keyTyped(KeyEvent e) {}

            @Override
            public void keyReleased(KeyEvent e) {}
        };
        return kl;
    }

    private void initUi() {
        this.setVisible(true);
        this.serverName = "localhost";
        this.port = 6800;
        this.name = "Anonym";
        this.nameField.setText(name);
        this.client = new Client(nameField.getText().trim());
        this.client.setRoom(roomField.getText().trim());
        chatTabsPane.setTitleAt(0, roomField.getText().trim());
    }

    private void exit() {
        disconnectedActions();
        client.disconnect();
        System.exit(0);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object action = e.getSource();

        if (action == loginButton) {
            if (!connected) {
                client = new Client(nameField.getText().trim());
                client.setRoom(roomField.getText().trim());
                TcpProxyAgent proxyAgent = new TcpProxyAgent(client);

                // add listeners
                client.addIncommingMessageListener(this);
                client.addSendMessageListener(proxyAgent);

                ClientMessage message = new ClientMessage(MessageType.CONNECT);
                message.setServerName(serverName);
                message.setPort(port);
                client.sendMessage(message);
            } else {
                disconnectedActions();
                client.disconnect();
                display("You are disconnected from the server!");
            }
            return;
        }

    }

    private void connectedActions() {
        connected = true;
        loginButton.setText("Logout");
        settingsButton.setEnabled(false);
        nameField.setEnabled(false);
    }

    private void disconnectedActions() {
        loginButton.setText("Login");
        settingsButton.setEnabled(true);
        nameField.setEnabled(true);
        client.removeIncommingMessageListener(this);
        connected = false;
    }

    @Override
    public void onIncommingMessage(ServerMessage message) {
        MessageType type = message.getType();

        switch (type) {
        case CONNECTED:
            connectedActions();
            display(Messages.getStringFromMessage(message));
            break;
        case DISCONNECTED:
            disconnectedActions();
            display(Messages.getStringFromMessage(message));
            break;
        case MESSAGE:
            display(message.getMessage());
            break;
        default:
            break;
        }
    }

    private void display(String message) {
        logTextArea.append(message);
        logTextArea.append("\n");
        logTextArea.setCaretPosition(logTextArea.getText().length() - 1);
    }

    public static void main(String[] args) {
        ChatUi ui = new ChatUi();
    }

}
